package com.tuuzed.android.ui;

import android.content.Context;
import android.content.res.TypedArray;
import android.os.Handler;
import android.support.annotation.AttrRes;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.tuuzed.android.util.DensityUtil;

import java.util.ArrayList;
import java.util.List;

public class CarouselView extends FrameLayout {
    private int mCount;
    private List<ImageView> mImageViews;
    private ViewPager mViewPager;
    private int mCurrentItem;
    private boolean isAutoPlay;
    /**
     * 自动播放间隔时间
     */
    private int mDelayTime;
    private int mDotFocus;
    private int mDotBlur;
    private int mLoadingPlaceholder;

    private LinearLayout mLinearLayoutDot;
    private List<ImageView> mImageDots;
    private OnItemClickListener mOnItemClickListener;
    private Runnable mPlayRunnable = new Runnable() {
        @Override
        public void run() {
            if (isAutoPlay) {
                mCurrentItem = mCurrentItem % (mCount + 1) + 1;
                if (mCurrentItem == 1) {
                    mViewPager.setCurrentItem(mCurrentItem, false);
                    post(this);
                } else {
                    mViewPager.setCurrentItem(mCurrentItem);
                    postDelayed(this, mDelayTime);
                }
            } else {
                postDelayed(this, mDelayTime);
            }
        }
    };


    public CarouselView(@NonNull Context context) {
        this(context, null);
    }

    public CarouselView(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CarouselView(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        obtainStyledAttrs(attrs);
        mImageViews = new ArrayList<>();
        mImageDots = new ArrayList<>();
        initLayout();
    }


    /**
     * 设置点击监听事件
     *
     * @param listener :监听器
     */
    public void setOnItemClickListener(OnItemClickListener listener) {
        this.mOnItemClickListener = listener;
    }

    /**
     * 设置加载远程图片
     *
     * @param imageLoader :图片加载器
     * @param imagesUrl   :远程图片Url数组
     */
    public void setImagesUrl(ImageLoader imageLoader, String[] imagesUrl) {
        initImgDot(mCount = imagesUrl.length);
        mImageViews.clear();
        for (int i = 0; i <= mCount + 1; i++) {
            ImageView imageView = new ImageView(getContext());
            imageView.setScaleType(ImageView.ScaleType.FIT_XY);
            imageView.setBackgroundResource(mLoadingPlaceholder);
            if (i == 0) {
                imageLoader.displayImage(imagesUrl[mCount - 1], imageView);
            } else if (i == mCount + 1) {
                imageLoader.displayImage(imagesUrl[0], imageView);
            } else {
                imageLoader.displayImage(imagesUrl[i - 1], imageView);
            }
            mImageViews.add(imageView);
        }
        startPlay();
    }

    /**
     * 设置加载资源图片
     *
     * @param imagesRes :资源图片ID
     */
    public void setImagesRes(@DrawableRes int[] imagesRes) {
        initImgDot(mCount = imagesRes.length);
        mImageViews.clear();
        for (int i = 0; i <= mCount + 1; i++) {
            ImageView imageView = new ImageView(getContext());
            imageView.setScaleType(ImageView.ScaleType.FIT_XY);
            imageView.setBackgroundResource(mLoadingPlaceholder);
            if (i == 0) {
                imageView.setImageResource(imagesRes[mCount - 1]);
            } else if (i == mCount + 1) {
                imageView.setImageResource(imagesRes[0]);
            } else {
                imageView.setImageResource(imagesRes[i - 1]);
            }
            mImageViews.add(imageView);
        }
        startPlay();
    }

    // 获取自定义属性
    private void obtainStyledAttrs(AttributeSet attrs) {
        TypedArray array = null;
        try {
            array = getContext().obtainStyledAttributes(attrs, R.styleable.CarouselView);
            mDelayTime = array.getInteger(R.styleable.CarouselView_cv_delay_time, 5000);
            mDotFocus = array.getInteger(R.styleable.CarouselView_cv_dot_focus, R.drawable.cv_dot_focus);
            mDotBlur = array.getInteger(R.styleable.CarouselView_cv_dot_focus, R.drawable.cv_dot_blur);
            mLoadingPlaceholder = array.getInteger(R.styleable.CarouselView_cv_loading_placeholder,
                    R.drawable.cv_placeholder_loading);
        } catch (Exception e) {
            e.printStackTrace();
            mDelayTime = 5000;
            mDotFocus = R.drawable.cv_dot_focus;
            mDotBlur = R.drawable.cv_dot_blur;
            mDotBlur = R.drawable.cv_dot_blur;
            mLoadingPlaceholder = R.drawable.cv_placeholder_loading;
        } finally {
            if (array != null) {
                array.recycle();
            }
        }
    }

    // 初始化布局
    private void initLayout() {
        // ViewPager
        mViewPager = new ViewPager(getContext());
        mViewPager.setLayoutParams(new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
        ));
        addView(mViewPager);
        // DotLayout
        mLinearLayoutDot = new LinearLayout(getContext());
        mLinearLayoutDot.setOrientation(LinearLayout.HORIZONTAL);
        mLinearLayoutDot.setGravity(Gravity.CENTER);
        int padding = DensityUtil.dip2px(getContext(), 6);
        mLinearLayoutDot.setPadding(padding, padding, padding, padding);
        LayoutParams params = new LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        params.gravity = Gravity.BOTTOM;
        mLinearLayoutDot.setLayoutParams(params);
        addView(mLinearLayoutDot);
    }

    // 初始化指示器
    private void initImgDot(int count) {
        for (int i = 0; i < count; i++) {
            ImageView imageDot = new ImageView(getContext());
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);
            params.leftMargin = 5;
            params.rightMargin = 5;
            if (i == 0) {
                imageDot.setImageResource(mDotFocus);
            } else {
                imageDot.setImageResource(mDotBlur);
            }
            mLinearLayoutDot.addView(imageDot, params);
            mImageDots.add(imageDot);
        }
    }

    // 开始播放
    private void startPlay() {
        mViewPager.setAdapter(new PagerAdapter() {
            @Override
            public int getCount() {
                return mImageViews.size();
            }

            @Override
            public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
                return view == object;
            }

            @NonNull
            @Override
            public Object instantiateItem(@NonNull ViewGroup container, final int position) {
                container.addView(mImageViews.get(position));
                //监听事件
                if (mOnItemClickListener != null) {
                    mImageViews.get(position).setOnClickListener(v -> mOnItemClickListener.onItemClick(v, position - 1));
                }
                return mImageViews.get(position);
            }

            @Override
            public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
                container.removeView(mImageViews.get(position));
            }
        });
        mViewPager.setFocusable(true);
        mCurrentItem = 1;
        mViewPager.setCurrentItem(mCurrentItem);
        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrollStateChanged(int state) {
                switch (state) {
                    case ViewPager.SCROLL_STATE_IDLE:
                        if (mViewPager.getCurrentItem() == 0) {
                            mViewPager.setCurrentItem(mCount, false);
                        } else if (mViewPager.getCurrentItem() == mCount + 1) {
                            mViewPager.setCurrentItem(1, false);
                        }
                        mCurrentItem = mViewPager.getCurrentItem();
                        isAutoPlay = true;
                        break;
                    case ViewPager.SCROLL_STATE_DRAGGING:
                        isAutoPlay = false;
                        break;
                    case ViewPager.SCROLL_STATE_SETTLING:
                        isAutoPlay = true;
                        break;
                }
            }

            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                for (int i = 0; i < mImageDots.size(); i++) {
                    if (i == position - 1) {
                        mImageDots.get(i).setImageResource(mDotFocus);
                    } else {
                        mImageDots.get(i).setImageResource(mDotBlur);
                    }
                }
            }
        });
        isAutoPlay = true;
        postDelayed(mPlayRunnable, mDelayTime);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        Handler handler = getHandler();
        if (handler!=null){
            handler.removeCallbacks(mPlayRunnable);
        }
    }

    /**
     * CarouselView Item点击监听器
     */
    public interface OnItemClickListener {
        void onItemClick(View view, int position);
    }
}